﻿package hu.vpszd.beans

import java.util.List;

import hu.vpszd.VpszdMailSender
import hu.vpszd.entities.Role
//import hu.vpszd.entities.Settlement;
import hu.vpszd.entities.User
import hu.vpszd.entities.customer.CheckingAccount
import hu.vpszd.entities.customer.Customer
import hu.vpszd.entities.transaction.ExistingLoanDebt
import hu.vpszd.entities.transaction.Income
import hu.vpszd.entities.transaction.LoanApplication
import hu.vpszd.entities.transaction.Transaction
import hu.vpszd.entities.transaction.Verification
import hu.vpszd.service.UserDetailsService
import hu.vpszd.services.CalculationService
import hu.vpszd.services.CheckingAccountService
import hu.vpszd.services.ContractService
import hu.vpszd.services.CustomerService
import hu.vpszd.services.LoanApplicationService
import hu.vpszd.services.MinimumConditionCheckingService
import hu.vpszd.services.OfferService
//import hu.vpszd.services.SettlementService
import hu.vpszd.services.TransactionService
import hu.vpszd.services.VerificationService

import javax.faces.bean.SessionScoped
import javax.faces.event.PhaseId
import javax.faces.event.ValueChangeEvent

import org.apache.log4j.Logger
import org.primefaces.event.FlowEvent
import org.primefaces.event.TabChangeEvent
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.authentication.encoding.Md5PasswordEncoder
import org.springframework.stereotype.Component

@Component("customerMaintBean")
@SessionScoped
class CustomerMaintBean implements Serializable{

	private static final Logger logger = Logger.getLogger(CustomerMaintBean.class);

	@Autowired
	private CustomerService customerService
	@Autowired
	private CheckingAccountService checkingAccountService
	@Autowired
	private LoanApplicationService loanApplicationService

	@Autowired
	private UserDetailsService userDetailsService

	@Autowired
	private MinimumConditionCheckingService minimumConditionCheckingService
	@Autowired
	private ContractService contractService
	@Autowired
	private CalculationService calculationService

	@Autowired
	private OfferService offerService

	@Autowired
	private VerificationService verificationService

	@Autowired
	private TransactionService transactionService

	@Autowired
	private VpszdMailSender mailSender

	@Autowired
	private Md5PasswordEncoder passwordEncoder

	boolean wasBornInHungary
	boolean isLivingInHungary
	boolean skip

	Customer customer = new Customer()
	CheckingAccount checkingAccount
	Transaction moneyTransfer
	LoanApplication loanApplication
	Income income = new Income()
	ExistingLoanDebt existingLoanDebt = new ExistingLoanDebt()
	Verification verification = new Verification()
	Transaction transaction = new Transaction()
	CheckingAccount checkingAccount1 = new CheckingAccount()
	CheckingAccount checkingAccount2 = new CheckingAccount()
	boolean canBeFinished = false

	String customerDataSheetPage = "customerData.xhtml"
	boolean edit
	Long customerId = 1

	Customer getCustomer() {
		return customer
	}

	void viewCustomerData() {
		customerDataSheetPage = "customerData.xhtml"
		//		print passwordEncoder.encodePassword("referens", "basicsalt")
		//		print passwordEncoder.encodePassword("admin", "basicsalt")
	}

	void viewCustomerDataChange() {
		customerDataSheetPage = "newCustomer.xhtml"
	}

	void viewCreateCheckingAccount() {
		customerDataSheetPage = "createCheckingAccount.xhtml"
	}

	void viewCheckingAccountDetalis() {
		customer = customerService.find(customer.id)
		customerDataSheetPage = "checkingAccountDetails.xhtml"

	}


	//	TODO
	String loanApplicationPage = "transaction/basicLoanData.xhtml"

	void viewMoneyTransfer(){
		customerDataSheetPage = "moneyTransfer.xhtml"
		//		moneyTransfer = new Transaction()
	}

	void viewBasicLoanData(){
		loanApplicationPage = "transaction/basicLoanData.xhtml"
	}
	void viewAdministrationData(){
		loanApplicationPage = "transaction/administrationData.xhtml"
	}
	void viewPersonalData(){
		loanApplication.birthday = customer.birthday
		loanApplication.citizenship = customer.citizenship
		loanApplication.education = customer.education
		loanApplication.maritalStatus = customer.maritalStatus
		loanApplication.address = customer.address
		loanApplication.residency = customer.residency
		loanApplication.emailAddress = customer.emailAddress
		loanApplication.mobilePhone = customer.mobilePhone
		loanApplication.wiredPhone = customer.wiredPhone
		loanApplication.otherPhone = customer.otherPhone;
		loanApplicationPage = "transaction/personalData.xhtml"
	}
	void viewIncomeData(){
		loanApplicationPage = "transaction/incomeData.xhtml"
	}
	void viewBankRelationshipData(){
		loanApplicationPage = "transaction/bankRelationshipData.xhtml"
	}
	void viewVerification(){
		loanApplicationPage = "transaction/verification.xhtml"
	}
	void viewRelatedDocuments(){
		loanApplicationPage = "transaction/relatedDocuments.xhtml"
	}
	void viewPrint(){
		loanApplicationPage = "transaction/print.xhtml"
	}

	void viewMinimumConditionChecking(){
		loanApplicationPage = "transaction/minimumConditionChecker.xhtml"
	}

	void viewResultScreen(){
		loanApplicationPage = "transaction/resultScreen.xhtml"
	}

	void viewDisbursement(){
		loanApplicationPage = "transaction/disbursement.xhtml"
	}

	//--------------------

	void loadCustomer(){
		if (customerId) {
			customer = customerService.find(Customer.class, customerId)
		}
		customerDataSheetPage = "customerData.xhtml"
		//		loanApplication = new LoanApplication()
		//		setEditTrue()
	}

	void saveCustomer() {
		//customer.setId(null)
		customerService.create(customer)
		mailSender.send("vp.05@hotmail.com", "Ügyfél account létrehozva", "teszt", "Gratulálunk, \nAz Ön adatait rögzítettük a rendszerben, Bankunk ügyfele lett. Az ön azonosítója: " + customer.id + " .\n\nÜdvözlettel, \nVarga Bank Zrt.");
		customer = new Customer()
	}

	void modifyCustomer(){
		customerService.save(customer)
	}

	void valueChange(ValueChangeEvent event) {
		wasBornInHungary = "Magyarország" == event.getNewValue()
	}

	public String onFlowProcess(FlowEvent event) {
		return event.getNewStep();
	}

	void onTabChange(TabChangeEvent event) {
	}

	void createCheckingAccount(){
		checkingAccount = new CheckingAccount();
		checkingAccountService.create(checkingAccount);
		//TODO: ez kell ide?
		customer.checkingAccounts.add(checkingAccount);
		checkingAccountService.save(checkingAccount)
		modifyCustomer();
	}

	void moneyTransfer(){
		transaction.date = new Date()
		transaction.starterBankAccount = checkingAccountService.findByBankAccountNumber(checkingAccount1.bankAccountNumber)
		transaction.beneficiaryBankAccount = checkingAccountService.findByBankAccountNumber(checkingAccount2.bankAccountNumber)
		checkingAccount1 = checkingAccountService.findByBankAccountNumber(checkingAccount1.bankAccountNumber)
		checkingAccount2 = checkingAccountService.findByBankAccountNumber(checkingAccount2.bankAccountNumber)

		checkingAccount1.outgoingTransactions.add(transaction)
		checkingAccount2.incomingTransactions.add(transaction)

		checkingAccountService.save(checkingAccount1)
		checkingAccountService.save(checkingAccount2)

		transaction = new Transaction()
		checkingAccount1 = new CheckingAccount()
		checkingAccount2 = new CheckingAccount()
	}

	void setEditTrue(){
		edit = true
	}

	void setEditFalse(){
		customer = new Customer()
		edit = false
	}

	void createLoanApplication(){
		loanApplication = new LoanApplication()
		loanApplicationService.create(loanApplication)
	}

	void createNewLoanApplication() {
		loanApplication = new LoanApplication()
		loanApplication.user = userDetailsService.currentUser
	}

	void addIncome() {
		loanApplication.incomes << new Income()
	}

	int deleteIncomeNumber

	void deleteIncome(){
		loanApplication.incomes.remove(deleteIncomeNumber)
	}

	int deleteExistingLoanDebtNumber

	void addExistingLoanDebt(){
		loanApplication.existingLoanDebts << new ExistingLoanDebt()
	}

	void deleteExistingLoanDebt(){
		loanApplication.existingLoanDebts.remove(deleteExistingLoanDebtNumber)
	}

	void minimumConditionChecking(){
		loanApplication = minimumConditionCheckingService.checkMinimumCondition(loanApplication)
	}

	void printOffer(){
		if(loanApplication.isMinimumConditionApproved){
			loanApplication = calculationService.calculation(loanApplication)
		}
		if(loanApplication.isCalculated && loanApplication.isOfferApproved && loanApplication.isMinimumConditionApproved){
			offerService.createOffer(loanApplication, customer)
			loanApplication.isOfferPrinted = true
			canBeFinished = true
		}
	}

	void printContract(){
		loanApplication = minimumConditionCheckingService.checkMinimumCondition(loanApplication)
		if(loanApplication.isMinimumConditionApproved){
			loanApplication = calculationService.calculation(loanApplication)
			if(loanApplication.isCalculated && loanApplication.isApplicationApproved && loanApplication.isMinimumConditionApproved){
				contractService.createContract(loanApplication, customer)
				loanApplication.isContractPrinted = true
			}
		}
		else{
			println("Az igénylés a minimumfeltétel kiértékelésen elbukott.")
		}
	}

	void signContract(){
		if(loanApplication.isCalculated && loanApplication.isApplicationApproved && loanApplication.isMinimumConditionApproved && loanApplication.isContractPrinted){
			loanApplication.isContractSigned = true
			canBeFinished = true
		}
		else{
			loanApplication.isContractSigned = false
		}
	}



	void setCanBeFinished(){
		loanApplication.status+=1
		loanApplicationService.save(loanApplication)
		createNewLoanApplication()
		canBeFinished = false
		customerDataSheetPage = "customerData.xhtml"
		loanApplicationPage = "transaction/basicLoanData.xhtml"
	}

	void closeTask(){
		if(loanApplication.status == 0){
			if(loanApplication.isCalculated && loanApplication.isOfferPrinted && loanApplication.isOfferApproved && loanApplication.isMinimumConditionApproved){
				loanApplication.status+=1
				loanApplicationService.create(loanApplication)
				//				canBeFinished = true
				canBeFinished = false
				createNewLoanApplication()
				customerDataSheetPage = "customerData.xhtml"
				loanApplicationPage = "transaction/basicLoanData.xhtml"
				createNewLoanApplication()
				println("create")
			}
			else{
				println("HIBA feladat befejezésénél")
			}
		}

		else if(loanApplication.status == 1){
			if(loanApplication.isCalculated && loanApplication.isOfferPrinted && loanApplication.isOfferApproved && loanApplication.isMinimumConditionApproved){
				loanApplication.status+=1
				loanApplicationService.save(loanApplication)
				canBeFinished = false
				createNewLoanApplication()
				customerDataSheetPage = "customerData.xhtml"
				loanApplicationPage = "transaction/basicLoanData.xhtml"
				println("save")

			}
			else{
				println("HIBA feladat befejezésénél")
			}
		}

		else if(loanApplication.status == 2){
			if(loanApplication.isVerificationApproved && loanApplication.isDisburesementSuccessful){
				loanApplication.status+=1
				loanApplicationService.save(loanApplication)
				canBeFinished = false
				println("Bírálat, folyósítás befejezése sikeres")
			}
			else{
				canBeFinished = false
				println("HIBA feladat befejezésénél bírálaton")
			}
		}

		else{
			println("Invalid loanApplication status")
		}
	}

	void loadLoanApplication(long id) {
		loanApplication = loanApplicationService.find(LoanApplication.class, id)
	}

	void setLoanTypeName(){
		for(ca in customer.checkingAccounts){
			if(loanApplication.bankAccountNumber == ca.bankAccountNumber){
				println("Egyezés, bankszámla beállítva")
			}
			else{
				println("Nincs egyezés, bankszámla nem lett beállítva")
			}
		}
		if(loanApplication.loanType == 1){
			loanApplication.loanTypeName = "Type 1"
		}
		else if(loanApplication.loanType == 2){
			loanApplication.loanTypeName = "Type 2"
		}
		else{
			loanApplication.loanTypeName = null
		}
	}

	void verificationEvaluation() {
		if(loanApplication.verification.hasAnyDebt == "Nem" && loanApplication.verification.hadAnyDelay == "Nem" && loanApplication.verification.isCheatingSuspiciousTransactionsOkay == "Igen"){
			loanApplication.isVerificationApproved = true
		}
		else{
			loanApplication.isVerificationApproved = false
		}
	}

	void disbursement(){
		Customer bank = customerService.getBank()

		transaction.starterBankAccount = checkingAccountService.findByBankAccountNumber(bank.checkingAccounts.get(0).bankAccountNumber)
		transaction.beneficiaryBankAccount = checkingAccountService.findByBankAccountNumber(loanApplication.bankAccountNumber)
		checkingAccount1 = checkingAccountService.findByBankAccountNumber(bank.checkingAccounts.get(0).bankAccountNumber)
		checkingAccount2 = checkingAccountService.findByBankAccountNumber(loanApplication.bankAccountNumber)

		transaction.date = new Date()
		transaction.sum = loanApplication.loanAmountByBank
		loanApplication.isDisburesementSuccessful = true

		checkingAccount1.outgoingTransactions.add(transaction)
		checkingAccount2.incomingTransactions.add(transaction)

		checkingAccountService.save(checkingAccount1)
		checkingAccountService.save(checkingAccount2)

		transaction = new Transaction()
		checkingAccount1 = new CheckingAccount()
		checkingAccount2 = new CheckingAccount()

		canBeFinished = true
		mailSender.send("vp.05@hotmail.com", "Folyósítás sikeres", "teszt", "Gratulálunk, \nAz Ön hitele folyósításra került. \n\nÜdvözlettel, \nXXXBank.");

	}

	boolean disableToStartLoanApplication(){
		User user = userDetailsService.currentUser;
		if (user.roles.contains(Role.REFERENS)) {
			logger.debug("Indíthat igénylést");
			return false
		}
		else if (user.roles.contains(Role.BIRALO)) {
			logger.debug("Nem indíthat igénylést");
			return true
		}
	}

	boolean userHasAdminRights(){
		User user = userDetailsService.currentUser;
		if (user.roles.contains(Role.ADMIN)) {
			logger.debug("Létrehozhat ügyfelet");
			return false
		}
		else{
			return true
		}
	}

}